<?php

namespace app\extra\H5WeixinSDK\V3;

use app\common\redis\db0\Weixin as weixinRedis;

/**
 * 统一支付接口类
 */
class JsApipub extends \app\extra\H5WeixinSDK\V3\Wxpayclientpub {

    var $code; //code码，用以获取openid
    var $openid; //用户的openid
    var $parameters; //jsapi参数，格式为json
    var $prepay_id; //使用统一支付接口得到的预支付id
    var $curl_timeout; //curl超时时间

    function __construct() {
        //设置curl超时时间
        $this->curl_timeout = 30;
    }

    /**
     * 	作用：生成可以获得code的url
     */
    function createOauthUrlForCode($redirectUrl, $scope = 'snsapi_base') {
        $urlObj["appid"] = WxPayConfpub::APPID;
        $urlObj["redirect_uri"] = urlencode($redirectUrl);
        $urlObj["response_type"] = "code";
        $urlObj["scope"] = $scope;
        $urlObj["state"] = "STATE" . "#wechat_redirect";
        $bizString = $this->formatBizQueryParaMap($urlObj, false);
        return "https://open.weixin.qq.com/connect/oauth2/authorize?" . $bizString;
    }

    /**
     * 	作用：生成可以获得openid的url
     */
    function createOauthUrlForOpenid() {
        $urlObj["appid"] = WxPayConfpub::APPID;
        $urlObj["secret"] = WxPayConfpub::APPSECRET;
        $urlObj["code"] = $this->code;
        $urlObj["grant_type"] = "authorization_code";
        $bizString = $this->formatBizQueryParaMap($urlObj, false);
        return "https://api.weixin.qq.com/sns/oauth2/access_token?" . $bizString;
    }

    /**
     * 	作用：生成可以获得access_token的url
     */
    function createOauthUrlForaccesstoken($openid, $access_token) {
        $urlObj["openid"] = $openid;
        $urlObj["access_token"] = $access_token;
        $urlObj["lang"] = "zh_CN";
        $bizString = $this->formatBizQueryParaMap($urlObj, false);
        return "https://api.weixin.qq.com/cgi-bin/user/info?" . $bizString;
    }

    /**
     * 	作用：生成可以获得临时素材的url
     */
    function createGetMedia($media_id, $access_token) {
        $urlObj["access_token"] = $access_token;
        $urlObj["media_id"] = $media_id;
        $bizString = $this->formatBizQueryParaMap($urlObj, false);
        return "https://api.weixin.qq.com/cgi-bin/media/get?" . $bizString;
    }

    /**
     * 	作用：生成可以获得access_token的url
     */
    function createOauthUrlForOpenIdAccesstoken($openid, $access_token) {
        $urlObj["openid"] = $openid;
        $urlObj["access_token"] = $access_token;
        $urlObj["lang"] = "zh_CN";
        $bizString = $this->formatBizQueryParaMap($urlObj, false);
        return "https://api.weixin.qq.com/sns/userinfo?" . $bizString;
    }

    /**
     * 	作用：通过curl向微信提交code，以获取openid
     */
    function getOpenid() {
        $url = $this->createOauthUrlForOpenid();
        //初始化curl
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //运行curl，结果以jason形式返回
        $res = curl_exec($ch);
        curl_close($ch);
        //取出openid
        $data = json_decode($res, true);

        if (isset($data['errcode'])) {
            exception($data['errmsg'], 1000111);
        }

        if (!isset($data['openid']) && rand(1, 10) == 5) {
            exception('微信openid：' . var_export($data, true) . 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'], 1000111);
        }

        $this->openid = $data['openid'];
        return $this->openid;
    }

    /**
     * 	作用：通过curl向微信提交code，以获取openid
     */
    function getOpenidall() {
        $url = $this->createOauthUrlForOpenid();
        //初始化curl
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //运行curl，结果以jason形式返回
        $res = curl_exec($ch);
        curl_close($ch);
        //取出openid
        $data = json_decode($res, true);

        return $data;
    }

    /**
     * 	作用：通过curl向微信提交media_id，以获取素材
     */
    function getMedia($media_id) {
        $redis = new weixinRedis();
        $access_token = $redis->find(WxPayConfpub::APPID);

        if (empty($access_token)) {
            $appid = WxPayConfpub::APPID;
            $secret = WxPayConfpub::APPSECRET;
            $token_json = file_get_contents("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $secret);

            $token_array = json_decode($token_json, true);
            $access_token = "";
            if (isset($token_array['access_token'])) {
                $access_token = $token_array['access_token'];
                $redis->update(WxPayConfpub::APPID, $access_token, 6000);
            }
        }
        $url = $this->createGetMedia($media_id, $access_token);
        $res = \Common::_getCurl($url);
        if (is_null($data = json_decode($res, true))) {
            $data = base64_encode($res);
        }
        //取出openid
        if (!is_string($data)) {
            \Our\Log::getInstance()->write('微信media_id：' . $media_id . var_export($data, true) . 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'], 'WXgetMedia.log');
        }

        return $data;
    }

    /**
     * 	作用：通过curl向微信提交code，以获取openid
     */
    function getOpeniduserinfo($openid, $access_token = '') {
        if (!$access_token) {
            $redis = new weixinRedis();
            $access_token = $redis->find(WxPayConfpub::APPID);

            if (empty($access_token)) {
                $appid = WxPayConfpub::APPID;
                $secret = WxPayConfpub::APPSECRET;
                $token_json = file_get_contents("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $secret);

                $token_array = json_decode($token_json, true);
                $access_token = "";
                if (isset($token_array['access_token'])) {
                    $access_token = $token_array['access_token'];
                    $redis->update(WxPayConfpub::APPID, $access_token, 6000);
                }
            }
            $url = $this->createOauthUrlForaccesstoken($openid, $access_token);
        } else {
            $url = $this->createOauthUrlForOpenIdAccesstoken($openid, $access_token);
        }


        //初始化curl
        $ch = curl_init();
        //设置超时
        curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        //运行curl，结果以jason形式返回
        $res = curl_exec($ch);
        curl_close($ch);
        //取出openid
        $data = json_decode($res, true);
        if (!isset($data['openid']) && rand(1, 10) == 5) {
            \Our\Log::getInstance()->write('微信openid：' . var_export($data, true) . 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'], 'WXuserinfo.log');
        }


        return $data;
    }

    /**
     * 	作用：通过curl  jsapi
     */
    function getjsapistr($url) {
        $appid = WxPayConfpub::APPID;
        $secret = WxPayConfpub::APPSECRET;

        $redis = new weixinRedis();
        $access_token = $redis->find(WxPayConfpub::APPID);
        if (empty($access_token)) {
            $appid = WxPayConfpub::APPID;
            $secret = WxPayConfpub::APPSECRET;
            $token_json = file_get_contents("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $secret);
            $token_array = json_decode($token_json, true);
            $access_token = "";
            if (isset($token_array['access_token'])) {
                $access_token = $token_array['access_token'];
                $redis->update(WxPayConfpub::APPID, $access_token, 6000);
            }
        }
        $ticket = $redis->find(WxPayConfpub::APPID . "ticket");
        if (empty($ticket)) {
            //   $access_token = file_get_contents("http://weixin.pba.cn/api/getaccesstoken?appid=" . $appid . "&secret=" . $secret);
            $url2 = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" . $access_token . "&type=jsapi";
            //初始化curl
            $ch = curl_init();
            //设置超时
            curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
            curl_setopt($ch, CURLOPT_URL, $url2);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($ch, CURLOPT_HEADER, FALSE);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
            //运行curl，结果以jason形式返回
            $res = curl_exec($ch);
            curl_close($ch);
            //取出openid
            $result = json_decode($res, true);
            if (!$result || $result["errcode"] != "0") {
                echo "get ticket error.";
                exit();
            }
            $ticket = $result['ticket'];
            $redis->update(WxPayConfpub::APPID . "ticket", $ticket, 6000);
        }
        $data['ticket'] = $ticket;

        $data['time'] = time();
       
       // $url = base64_decode($url);

        $data['nonceStr'] = $this->createNoncestrs();
        $data['signature'] = sha1("jsapi_ticket=" . $data['ticket'] . "&noncestr=" . $data['nonceStr'] . "&timestamp=" . $data['time'] . "&url=" . $url);
        $data['appid'] = $appid;
        $data['url'] = $url;
        $data['str'] = "jsapi_ticket=" . $data['ticket'] . "&noncestr=" . $data['nonceStr'] . "&timestamp=" . $data['time'] . "&url=" . $url;
        return $data;
    }

    /**
     * 	作用：产生随机字符串，不长于32位
     */
    public function createNoncestrs($length = 32) {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str.= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    /**
     * 	作用：设置prepay_id
     */
    function setPrepayId($prepayId) {
        $this->prepay_id = $prepayId;
    }

    /**
     * 	作用：设置code
     */
    function setCode($code_) {
        $this->code = $code_;
    }

    /**
     * 	作用：设置jsapi的参数
     */
    public function getParametersapp($parameter) {
        $jsApiObj = $parameter;
        $jsApiObj2['appid'] = WxPayConfpubapp::APPID;
        $jsApiObj2['partnerid'] = WxPayConfpubapp::MCHID;
        $jsApiObj2['prepayid'] = $parameter['prepay_id'];
        $jsApiObj2['timestamp'] = strval(time());
        $jsApiObj2['noncestr'] = $this->createNoncestr();
        $jsApiObj2["package"] = "Sign=WXPay";
        $jsApiObj2["sign"] = $this->getSignapp($jsApiObj2);
        return $jsApiObj2;
    }

    /**
     * 	作用：设置jsapi的参数
     */
    public function getParametersapp2($parameter) {
        $jsApiObj = $parameter;
        $jsApiObj2['appid'] = WxPayConfpubapp::APPID;
        $jsApiObj2['partnerid'] = WxPayConfpubapp::MCHID;
        $jsApiObj2['prepayid'] = $parameter['prepay_id'];
        $jsApiObj2['timestamp'] = strval(time());
        $jsApiObj2['noncestr'] = $this->createNoncestr();
        $jsApiObj2["package"] = "Sign=WXPay";
        $jsApiObj['appid'] = WxPayConfpubapp::APPID;
        $jsApiObj['partnerid'] = WxPayConfpubapp::MCHID;
        $jsApiObj['prepayid'] = $parameter['prepay_id'];
        $jsApiObj['timestamp'] = strval(time());
        $jsApiObj['noncestr'] = $this->createNoncestr();
        $jsApiObj["package"] = "Sign=WXPay";
        $jsApiObj["sign"] = $this->getSignapp($jsApiObj2);
        $jsApiObj['traceid'] = $parameter['out_trade_no'];
        $jsApiObj['app_signature'] = $parameter['sign'];
        $jsApiObj['sign_method'] = "MD5";
        return $jsApiObj;
    }

    /**
     * 	作用：设置jsapi的参数
     */
    public function getParameters() {
        $jsApiObj["appId"] = WxPayConfpub::APPID;
        $jsApiObj["timeStamp"] = strval(time());
        $jsApiObj["nonceStr"] = $this->createNoncestr();
        $jsApiObj["package"] = "prepay_id=$this->prepay_id";
        $jsApiObj["signType"] = "MD5";
        $jsApiObj["paySign"] = $this->getSign($jsApiObj);
        $this->parameters = json_encode($jsApiObj);

        return $this->parameters;
    }

    /**
     * 微信支付回调数据的验证
     * 
     */
    public function verifySignature($get, $sign) {
//商户号
        if (!isset($get['mch_id']) || empty($get['mch_id']) || $get['mch_id'] != WxPayConfpubapp::MCHID) {
            return false;
        }
//支付状态
        if (!isset($get['result_code']) || $get['result_code'] !== 'SUCCESS') {
            return false;
        }
//支付状态
        if (!isset($get['sign']) || empty($get['sign'])) {
            return false;
        }
        unset($get['sign']);
        $calculateSign = $this->getSignapp($get);
        return $calculateSign == $sign;
    }

    /**
     * 微信支付回调数据的验证
     * 
     */
    public function verifySignaturewap($get, $sign) {
//商户号
        if (!isset($get['mch_id']) || empty($get['mch_id']) || $get['mch_id'] != WxPayConfpub::MCHID) {
            return false;
        }
//支付状态
        if (!isset($get['result_code']) || $get['result_code'] !== 'SUCCESS') {
            return false;
        }
//支付状态
        if (!isset($get['sign']) || empty($get['sign'])) {
            return false;
        }
        unset($get['sign']);
        $calculateSign = $this->getSign($get);
        return $calculateSign == $sign;
    }

    /**
     * 获取普通access_token,非网页授权access_token
     */
    public function getCommonAccessToken() {
        $redis = \Redis\Db4\WeixinTokenModel::getInstance();
        $access_token = $redis->find(WxPayConfpub::APPID);
        if (empty($access_token)) {
            $appid = WxPayConfpub::APPID;
            $secret = WxPayConfpub::APPSECRET;
            $token_json = file_get_contents("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $secret);

            $token_array = json_decode($token_json, true);
            $access_token = "";
            if (isset($token_array['access_token'])) {
                $access_token = $token_array['access_token'];
                $redis->update(WxPayConfpub::APPID, $access_token, 6000);
            }
        }
        return $access_token;
    }

    /**
     * 作用：原生扫码支付
     * */
    public function codenative($post) {
        if (isset($post['order_amount']) && $post['order_amount'] > 0 && isset($post['out_trade_no']) && $post['out_trade_no']) {
            $wxPayHelper = new WxPayPubHelper();
            $post = $wxPayHelper->qrcode($post);
            return $post;
        }
        return false;
    }

}
